/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-07-07     Lenovo       the first version
 */

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <errno.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <rtdbg.h>
#include <rtdef.h>

#include <wlan_mgnt.h>
#include <wlan_prot.h>
#include <wlan_cfg.h>
#include <spi_wifi_rw007.h>
#include <wifi2.h>

#define WLAN_SSID "mofish"
#define WLAN_PASSWORD  "11111111"
#define NET_READY_TIME_OUT (rt_tick_from_millisecond(15 * 1000))

void print_wlan_information(struct rt_wlan_info *info,int index);
int wifi_autoconnect(void);

struct rt_semaphore net_ready;
struct rt_semaphore scan_done;
struct rt_wlan_info info;

/* 执行扫描 */
void saomiaoredian(void)
{
    static int i = 0;
    int result = RT_EOK;

    rt_sem_init(&scan_done,"scan_done",0,RT_IPC_FLAG_FIFO);
    rt_wlan_register_event_handler(RT_WLAN_EVT_SCAN_REPORT, wlan_scan_report_hander,&i);
    rt_wlan_register_event_handler(RT_WLAN_EVT_SCAN_DONE, wlan_scan_done_hander,RT_NULL);
    if(rt_wlan_scan() == RT_EOK)
    {
        LOG_D("the scan is started...");
    }else
    {
        LOG_E("scan failed");
    }
    /* 等待扫描完毕 */
    rt_sem_take(&scan_done,RT_WAITING_FOREVER);
}

void wlan_scan_report_hander(int event,struct rt_wlan_buff *buff,void *parameter)
{
    struct rt_wlan_info *info = RT_NULL;
    int index = 0;
    RT_ASSERT(event == RT_WLAN_EVT_SCAN_REPORT);
    RT_ASSERT(buff != RT_NULL);
    RT_ASSERT(parameter != RT_NULL);
    info = (struct rt_wlan_info *)buff->data;
    index = *((int *)(parameter));
    print_wlan_information(info,index);
    ++ *((int *)(parameter));
}
void wlan_scan_done_hander(int event,struct rt_wlan_buff *buff,void *parameter)
{
    RT_ASSERT(event == RT_WLAN_EVT_SCAN_DONE);
    rt_sem_release(&scan_done);
}

void wlan_ready_handler(int event, struct rt_wlan_buff *buff, void *parameter)
{
    rt_sem_release(&net_ready);
}

/* 断开连接回调函数 */
void wlan_station_disconnect_handler(int event, struct rt_wlan_buff *buff, void *parameter)
{
    LOG_I("disconnect from the network!");
}

void wlan_connect_handler(int event, struct rt_wlan_buff *buff, void *parameter)
{
    rt_kprintf("%s\n", __FUNCTION__);
    if ((buff != RT_NULL) && (buff->len == sizeof(struct rt_wlan_info)))
    {
        rt_kprintf("ssid : %s \n", ((struct rt_wlan_info *)buff->data)->ssid.val);
    }
}

void wlan_connect_fail_handler(int event, struct rt_wlan_buff *buff, void *parameter)
{
    rt_kprintf("%s\n", __FUNCTION__);
    if ((buff != RT_NULL) && (buff->len == sizeof(struct rt_wlan_info)))
    {
        rt_kprintf("ssid : %s \n", ((struct rt_wlan_info *)buff->data)->ssid.val);
    }
}

void lianjie()
{
    int result = RT_EOK;
    /* 热点连接 */
     LOG_D("start to connect ap ...");
     rt_sem_init(&net_ready, "net_ready", 0, RT_IPC_FLAG_FIFO);
     /* 注册 wlan ready 回调函数 */
     rt_wlan_register_event_handler(RT_WLAN_EVT_READY, wlan_ready_handler, RT_NULL);
     /* 注册 wlan 断开回调函数 */
     rt_wlan_register_event_handler(RT_WLAN_EVT_STA_DISCONNECTED, wlan_station_disconnect_handler, RT_NULL);
     /* 同步连接热点 */
     result = rt_wlan_connect(WLAN_SSID, WLAN_PASSWORD);
     if (result == RT_EOK)
     {
         rt_memset(&info, 0, sizeof(struct rt_wlan_info));
         /* 获取当前连接热点信息 */
         rt_wlan_get_info(&info);
         LOG_D("station information:");
         print_wlan_information(&info,0);
         /* 等待成功获取 IP */
         result = rt_sem_take(&net_ready, NET_READY_TIME_OUT);
         if (result == RT_EOK)
         {
             LOG_D("networking ready!");
             msh_exec("ifconfig", rt_strlen("ifconfig"));
         }
         else
         {
             LOG_D("wait ip got timeout!");
         }
         /* 回收资源 */
         rt_wlan_unregister_event_handler(RT_WLAN_EVT_READY);
         rt_sem_detach(&net_ready);
     }
     else
     {
         LOG_E("The AP(%s) is connect failed!", WLAN_SSID);
     }
}

void print_wlan_information(struct rt_wlan_info *info,int index)
{
        char *security;

        if(index == 0)
        {
            rt_kprintf("             SSID                      MAC            security    rssi chn Mbps\n");
            rt_kprintf("------------------------------- -----------------  -------------- ---- --- ----\n");
        }

        {
            rt_kprintf("%-32.32s", &(info->ssid.val[0]));
            rt_kprintf("%02x:%02x:%02x:%02x:%02x:%02x  ",
                    info->bssid[0],
                    info->bssid[1],
                    info->bssid[2],
                    info->bssid[3],
                    info->bssid[4],
                    info->bssid[5]
                    );
            switch (info->security)
            {
            case SECURITY_OPEN:
                security = "OPEN";
                break;
            case SECURITY_WEP_PSK:
                security = "WEP_PSK";
                break;
            case SECURITY_WEP_SHARED:
                security = "WEP_SHARED";
                break;
            case SECURITY_WPA_TKIP_PSK:
                security = "WPA_TKIP_PSK";
                break;
            case SECURITY_WPA_AES_PSK:
                security = "WPA_AES_PSK";
                break;
            case SECURITY_WPA2_AES_PSK:
                security = "WPA2_AES_PSK";
                break;
            case SECURITY_WPA2_TKIP_PSK:
                security = "WPA2_TKIP_PSK";
                break;
            case SECURITY_WPA2_MIXED_PSK:
                security = "WPA2_MIXED_PSK";
                break;
            case SECURITY_WPS_OPEN:
                security = "WPS_OPEN";
                break;
            case SECURITY_WPS_SECURE:
                security = "WPS_SECURE";
                break;
            default:
                security = "UNKNOWN";
                break;
            }
            rt_kprintf("%-14.14s ", security);
            rt_kprintf("%-4d ", info->rssi);
            rt_kprintf("%3d ", info->channel);
            rt_kprintf("%4d\n", info->datarate / 1000000);
        }
}

int wifi_autoconnect(void)
{
    /* Configuring WLAN device working mode */
    rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION);
    /* Start automatic connection */
    rt_wlan_config_autoreconnect(RT_TRUE);
    /* register event */
    rt_wlan_register_event_handler(RT_WLAN_EVT_STA_CONNECTED, wlan_connect_handler, RT_NULL);
    rt_wlan_register_event_handler(RT_WLAN_EVT_STA_CONNECTED_FAIL, wlan_connect_fail_handler, RT_NULL);
    return 0;
}

void wifi_thread_entry(void *parameter)
{
    saomiaoredian();
    lianjie();
}









